<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\App\WorkRoom\Action\Workbench;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\WorkbenchAuthMiddleware;
use MoChat\App\User\Contract\UserContract;
use MoChat\App\WorkContact\Contract\WorkContactRoomContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\App\WorkRoom\Contract\WorkRoomContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Plugin\RoomTag\Contract\RoomTagContract;
use MoChat\Plugin\RoomTag\Contract\RoomTagPivotContract;

/**
 * 客户群列表.
 *
 * Class Index.
 * @Controller
 */
class Index extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Inject
     * @var WorkRoomContract
     */
    protected $workRoomService;

    /**
     * @Inject
     * @var WorkContactRoomContract
     */
    protected $workContactRoomService;

    /**
     * @Inject
     * @var UserContract
     */
    protected $userService;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Inject
     * @var RoomTagPivotContract
     */
    protected $roomTagPivotService;

    /**
     * @Inject
     * @var RoomTagContract
     */
    protected $roomTagService;

    /**
     * @Middlewares({
     *     @Middleware(WorkbenchAuthMiddleware::class)
     * })
     * @RequestMapping(path="/workbench/workRoom/index", methods="get")
     * @return array 返回数组
     */
    public function handle(): array
    {
        $user = user();
        // 判断用户绑定企业信息
        if (! isset($user['corpId'])) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        $params = [
            'name' => $this->request->input('name', ''),
            'page' => $this->request->input('page', 1),
            'perPage' => $this->request->input('perPage', 10),
        ];
        $params['userId'] = (int) $user['logUserId'];
        $params['corpId'] = $user['corpId'];
        $params['employeeId'] = $user['id'];
        // 接收参数
        $params['day'] = $this->request->input('day');
        // 参数验证
        $this->validated($params);
        // 处理参数
        $params = $this->handleParam($params);

        return $this->getRoomsList($params);
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
        ];
    }

    private function getRoomsList($params): array
    {
        $columns = ['id', 'name', 'owner_id', 'create_time'];
        // 所有客户群
        $rooms = $this->workRoomService->getWorkRoomList($params['where'], $columns, $params['options']);

        $data = [
            'page' => [
                'perPage' => 0,
                'total' => '0',
                'totalPage' => '0',
            ],
            'list' => [],
        ];

        return empty($rooms['data']) ? $data : $this->handleData($rooms);
    }

    /**
     * 处理参数.
     * @param array $params 接受参数
     * @return array 响应数组
     */
    private function handleParam(array $params): array
    {
        $where['corp_id'] = $params['corpId'];
        if ($params['userId'] > 0) {
            $userInfo = $this->userService->getUserById($params['userId'], ['is_root']);
            $userInfo['isRoot'] === 0 && $where['owner_id'] = $params['employeeId'];
        }
        if (! empty($params['name'])) {
            $where[] = ['name', 'like', '%' . $params['name'] . '%'];
        }
        $options = [
            'perPage' => $params['perPage'],
            'page' => $params['page'],
            'orderByRaw' => 'id desc',
        ];
        return ['where' => $where, 'options' => $options];
    }

    private function handleData(array $rooms): array
    {
        $employeeIds = array_column($rooms['data'], 'ownerId');
        $employees = $this->workEmployeeService->getWorkEmployeesById($employeeIds, ['id', 'name']);
        $employees = array_column($employees, null, 'id');
        foreach ($rooms['data'] as &$item) {
            $item['ownerName'] = empty($employees[$item['ownerId']]) ? '' : $employees[$item['ownerId']]['name'];
            $item['tags'] = [];
            $roomTags = $this->roomTagPivotService->getRoomTagPivotsByRoomIdTagId($item['id'], 0, ['room_tag_id']);
            if (! empty($roomTags)) {
                $tagIds = array_column($roomTags, 'roomTagId');
                $tags = $this->roomTagService->getRoomTagsById($tagIds, ['name']);
                if (! empty($tags)) {
                    $item['tags'] = array_column($tags, 'name');
                }
            }
            $item['total'] = $this->workContactRoomService->countWorkContactRoomByRoomId($item['id']);
        }
        unset($item);
        $data['page']['total'] = $rooms['total'];
        $data['page']['totalPage'] = $rooms['last_page'];
        $data['list'] = $rooms['data'];
        return $data;
    }
}
